package com.lws.custominitializer;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.startup.AppInitializer;
import androidx.startup.Initializer;

import java.util.Set;


public final class CustomInitializer {

    private static final String TAG = "CustomInitializer";

    /**
     * The {@link CustomInitializer} instance.
     */
    private static volatile CustomInitializer sInstance;

    /**
     * Guards app initialization.
     */
    private static final Object sLock = new Object();


    @NonNull
    final Context mContext;

    /**
     * Creates an instance of {@link CustomInitializer}
     *
     * @param context The application context
     */
    CustomInitializer(@NonNull Context context) {
        mContext = context.getApplicationContext();
    }

    /**
     * @param context The Application {@link Context}
     * @return The instance of {@link CustomInitializer} after initialization.
     */
    @NonNull
    @SuppressWarnings("UnusedReturnValue")
    public static CustomInitializer getInstance(@NonNull Context context) {
        if (sInstance == null) {
            synchronized (sLock) {
                if (sInstance == null) {
                    sInstance = new CustomInitializer(context);
                }
            }
        }
        return sInstance;
    }


    @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"})
    public void discoverAndInitialize(String type) {
        try {
            PackageInfo packageInfo = mContext.getPackageManager().
                    getPackageInfo(mContext.getPackageName(), PackageManager.GET_META_DATA);
            ApplicationInfo applicationInfo = packageInfo.applicationInfo;
            Bundle metadata = applicationInfo.metaData;
            if (metadata != null) {
                Set<String> keys = metadata.keySet();
                for (String key : keys) {
                    String value = metadata.getString(key, null);
                    if (type.equals(value)) {
                        Class<?> clazz = Class.forName(key);
                        if (Initializer.class.isAssignableFrom(clazz)) {
                            Class<? extends Initializer<Object>> component = (Class<? extends Initializer<Object>>) clazz;
                            AppInitializer.getInstance(mContext).initializeComponent(component);
                        }
                    }
                }
            }
        } catch (PackageManager.NameNotFoundException | ClassNotFoundException exception) {
            Log.e(TAG, "discoverAndInitialize:  ", exception);
        }
    }
}
